#ifndef K_DEBUG_CLIENT_H
#define K_DEBUG_CLIENT_H
#pragma once

#include "KNetScene.h"
#include "KStreamAction.h"
#include <cstdint>
#include <string>

class KDebugClient;

class KDebugAction : public KStreamAction {
private:
    explicit KDebugAction(KPageList *pool = NULL);
    friend class KDebugClient;
protected:
    KDebugClient *client() const;
protected:
    virtual void abortImp();
    virtual void onError(KDef::SockError type, DWORD error);
    virtual void process(KStorage *storage, bool ok);
private:
    int m_state;
    size_t m_length;
};

class KDebugClient : public KNetItem, protected KLockable {
public:
    explicit KDebugClient(KPageList *pool = NULL);
public:
    bool isConnected() const    { return m_connection != NULL; }
public:
    void abort();
    bool connect(const KIAddress &address);
protected:
    virtual int filter() const
    {
        return KNetItem::FilterConnected
            | KNetItem::FilterError
            | KNetItem::FilterReceived;
    }
protected:
    virtual void onDebugBegin();
    virtual void onDebugAttr(uint32_t backColor, uint32_t foreColor) {}
    virtual void onDebugText(const std::string &text);
    virtual void onDebugTitle(const std::string &title) {}
    virtual void onDebugEnd();
protected:
    virtual void onStopped();
    virtual void onConnected(KSocket *sock);
private:
    KDebugAction *volatile m_connection;
    KPageList *const m_pool;
    friend class KDebugAction;
};

#endif // K_DEBUG_CLIENT_H